package cn.tedu.csmall.stock.webapi.controller;

import cn.tedu.csmall.commons.exception.CoolSharkServiceException;
import cn.tedu.csmall.commons.pojo.stock.dto.StockReduceCountDTO;
import cn.tedu.csmall.commons.restful.JsonResult;

import cn.tedu.csmall.commons.restful.ResponseCode;
import cn.tedu.csmall.stock.service.IStockService;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import netscape.javascript.JSObject;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/base/stock")
@Api(tags = "库存管理模块")
public class StockController {
    @Autowired
    private IStockService stockService;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/reduce/count")
    @ApiOperation("减少库存数")
    //  @SentinelResource注解需要标记在控制层方法上，在该方法第一次运行后，会被Sentinel仪表台检测
    //  该方法在运行前，不会出现在仪表台中
    //  括号中"减少库存数"这个描述会出现在仪表台上，代表这个方法
    //  blockHandler可以设置当前控制器方法
//    @SentinelResource(value = "减少库存数",
//                      blockHandler = "blockError",
//                      fallback = "fallbackError"
//                )
    public JsonResult reduceCommodityCount(StockReduceCountDTO stockReduceCountDTO){
        stockService.reduceCommodityCount(stockReduceCountDTO);
        String url="http://localhost:20001/base/cart/add?" +
                "commodityCode={1}&price={2}$count={3}&userId={4}";
        JsonResult jsonResult = restTemplate
                .getForObject(url, JsonResult.class,
                        stockReduceCountDTO.getCommodityCode(), 20,
                        stockReduceCountDTO.getReduceCount(), "UU100");
        System.out.println(jsonResult);
        // 随机发生异常,测试自定义降级方法效果
//        if(Math.random()<0.5) {
//            throw new CoolSharkServiceException(
//                    ResponseCode.INTERNAL_SERVER_ERROR, "发生随机异常");
//        }
//        try {
//            Thread.sleep(5000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        return JsonResult.ok("减少库存完成！");
    }

    public JsonResult blockError(StockReduceCountDTO stockReduceCountDTO,
                                 BlockException e){
        // 这个方法运行表示当前请求被限流了，我们给与返回，提示它被限流即可
        return JsonResult.failed(
                ResponseCode.INTERNAL_SERVER_ERROR,"服务器忙，请稍后再试");
    }

    // 自定以降级方法： 由@SentinelResourcede的fallback属性指定
    // 自定义降级方法和自定义限流方法的格式规则基本一致
    // 只是额外返回的异常类型使用Throwable
    // 当上面的控制层方法发生异常时,会调用自定义降级方法
    // 实际开发中,可能调用运行一些老版本的代码,所以称之为"降级"
    public JsonResult fallbackError(StockReduceCountDTO stockReduceCountDTO,
                                    Throwable throwable){
        throwable.printStackTrace();
        return JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR,"服务降级");
    }

}
